package juc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *线程池 4 个组成部分:
 *  线程池管理器：用于创建并管理线程池
 *  工作线程：线程池中的线程
 *  任务接口：每个任务必须实现的接口，用于工作线程调度其运行
 *  任务队列：用于存放待处理的任务，提供一种缓冲机制
 * 线程池 7大核心参数
 *  corePoolSize：核心线程数。 【指线程池中长期存活的线程数】
 *  maximumPoolSize：最大线程数。【线程池允许创建的最大线程数量，当线程池的任务队列满了之后，可以创建的最大线程数】
 *  keepAliveTime：空闲线程存活时间。【当线程池中没有任务时，会销毁一些线程，销毁的线程数=maximumPoolSize（最大线程数）-corePoolSize（核心线程数）】
 *  TimeUnit：时间单位。
 *  BlockingQueue：线程池任务队列。
         ArrayBlockingQueue：一个由数组结构组成的有界阻塞队列。
         LinkedBlockingQueue：一个由链表结构组成的有界阻塞队列。
         SynchronousQueue：一个不存储元素的阻塞队列，即直接提交给线程不保持它们。
         PriorityBlockingQueue：一个支持优先级排序的无界阻塞队列。
         DelayQueue：一个使用优先级队列实现的无界阻塞队列，只有在延迟期满时才能从中提取元素。
         LinkedTransferQueue：一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似，还含有非阻塞方法。
         LinkedBlockingDeque：一个由链表结构组成的双向阻塞队列。
 *  ThreadFactory：创建线程的工厂。
 *  RejectedExecutionHandler：拒绝策略。
         AbortPolicy：拒绝并抛出异常。
         CallerRunsPolicy：使用当前调用的线程来执行此任务。
         DiscardOldestPolicy：抛弃队列头部（最旧）的一个任务，并执行当前任务。
         DiscardPolicy：忽略并抛弃当前任务。
 *
 *1、守护线程?
 * 是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。在 Java 中垃圾回收线程就是特殊的守护线程。
 * 2、创建线程有哪4种方式？
 * 继承 Thread 重写 run 方法；
 * 实现 Runnable 接口；   【execute()：只能执行 Runnable 类型的任务；submit()：可以执行 Runnable 和 Callable 类型的任务。】
 * 实现 Callable 接口。 【runnable 没有返回值，callable 可以拿到有返回值，callable 可以看作是 runnable 的补充。】
 * 使用 Executors 工具类创建线程池
 * 3、线程池创建有七种方式，最核心的是最后一种
 * newSingleThreadExecutor()：它的特点在于工作线程数目被限制为 1，操作一个无界的工作队列，所以它保证了所有任务的都是被顺序执行，最多会有一个任务处于活动状态，并且不允许使用者改动线程池实例，因此可以避免其改变线程数目；
 * newCachedThreadPool()：它是一种用来处理大量短时间工作任务的线程池，具有几个鲜明特点：它会试图缓存线程并重用，当无缓存线程可用时，就会创建新的工作线程；如果线程闲置的时间超过 60 秒，则被终止并移出缓存；长时间闲置时，这种线程池，不会消耗什么资源。其内部使用 SynchronousQueue 作为工作队列；
 * newFixedThreadPool(int nThreads)：重用指定数目（nThreads）的线程，其背后使用的是无界的工作队列，任何时候最多有 nThreads 个工作线程是活动的。这意味着，如果任务数量超过了活动队列数目，将在工作队列中等待空闲线程出现；如果有工作线程退出，将会有新的工作线程被创建，以补足指定的数目 nThreads；
 * newSingleThreadScheduledExecutor()：创建单线程池，返回 ScheduledExecutorService，可以进行定时或周期性的工作调度；
 * newScheduledThreadPool(int corePoolSize)：和newSingleThreadScheduledExecutor()类似，创建的是个 ScheduledExecutorService，可以进行定时或周期性的工作调度，区别在于单一工作线程还是多个工作线程；
 * newWorkStealingPool(int parallelism)：这是一个经常被人忽略的线程池，Java 8 才加入这个创建方法，其内部会构建ForkJoinPool，利用Work-Stealing算法，并行地处理任务，不保证处理顺序；
 * ThreadPoolExecutor()：是最原始的线程池创建，上面1-3创建方式都是对ThreadPoolExecutor的封装。
 */
public class MyThreadPool {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        int i =10;
        while(i>0) {
            i--;
            threadPool.execute(new Runnable() { // 提交多个线程任务，并执行
                @Override
                public void run() {

                    System.out.println(Thread.currentThread().getName() + " is running ..");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

}
